package newcrunch.grader;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.TableModel;
import newcrunch.gui.RightPanel;
import newcrunch.util.DisplayHelper;
import newcrunch.util.Misc;

/**
 *
 * @author ccadm
 */
public class GradingPanel extends javax.swing.JPanel {
    private RightPanel rightPanel;
    private SubmissionsManager submissionsManager;
        
    /**
     * Creates new form GradingPanel
     */
    public GradingPanel() {
        initComponents();
        
        submissionsManager = new SubmissionsManager(this);
        
        gradingPanelPopup.addPopupMenuListener(new PopupMenuListener(){
            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                Point loc = GradingPanel.this.getMousePosition();
                SwingUtilities.convertPointToScreen(loc, GradingPanel.this);
                SwingUtilities.convertPointFromScreen(loc, ungradedList);
                updateRightClick(loc);
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
            
        });
    }
    
    public SubmissionsManager getSubmissionsManager()
    {
        return submissionsManager;
    }
    
    public void setRightPanel(RightPanel panel)
    {
        this.rightPanel = panel;
        
        panel.addPropertyChangeListener(new PropertyChangeListener(){
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("displayPropsDialog".equals(evt.getPropertyName()))
                    displayPropsDialog((SubmissionInfo)evt.getNewValue());
            }
        });
    }
    
    public GradingList getUngradedList()
    {
        return ungradedList;
    }
    
    public GradingList getGradedList()
    {
        return gradedList;
    }
    
    public RightPanel getRightPanel()
    {
        return rightPanel;
    }
    
    public JTabbedPane getTabbedPane()
    {
        return tabbedPane;
    }
    
    private void updateRightClick(Point point)
    {
        Component selectedComp = tabbedPane.getSelectedComponent();
        GradingList targetList = null;
        
        if (ungradedPanel.equals(selectedComp))
            targetList = ungradedList;
        
        else if (gradedPanel.equals(selectedComp))
            targetList = gradedList;
        
        if (targetList != null)
        {
            int index = targetList.locationToIndex(point);
            GradingListModel model = targetList.getGradingListModel();
            if (index != -1)
            {
                targetList.clearSelection();
                targetList.setSelectedIndex(index);
                showNameItem.setEnabled(!model.isShowingName(index));
                hideNameItem.setEnabled(!showNameItem.isEnabled());
                propsItem.setEnabled(true);
            }
            else
            {
                showNameItem.setEnabled(false);
                hideNameItem.setEnabled(false);
                propsItem.setEnabled(false);
            }
            
            hideAllNamesItem.setEnabled(model.getShowNameCount() > 0);
            showAllNamesItem.setEnabled(model.getSize() > 0 && model.getShowNameCount() != model.getSize());
        }
    }
    
    private void processGradingListMouseClick(final java.awt.event.MouseEvent evt)
    {
        if (evt.getButton() == MouseEvent.BUTTON3)
        {
            Point point = this.getMousePosition();
            SwingUtilities.convertPointToScreen(point, GradingPanel.this);
            gradingPanelPopup.setLocation(point);
            
            GradingList target = (GradingList)(evt.getSource());
            SwingUtilities.convertPointFromScreen(point, target);
            target.setSelectedIndex(target.locationToIndex(point));
            
            Point currPos = this.getMousePosition();
            gradingPanelPopup.show(this, currPos.x, currPos.y);
        }
        
        else if (evt.getButton() == MouseEvent.BUTTON1)
        {
            if (evt.getClickCount() == 2)
            {                
                submissionsManager.loadSubmission((GradingList)(evt.getSource()),
                                evt.getPoint());
            }
            else
                gradingPanelPopup.setVisible(false);
        }
    }
    
    public void selectInPanel(SubmissionInfo info)
    {
        GradingList[] lists = { gradedList, ungradedList };
        
        for (GradingList list : lists)
        {
            //search in graded list
            GradingListModel model = list.getGradingListModel();
            String infoUsername = info.username;
            for (int i = 0; i < model.getSize(); i++)
            {
                if (submissionsManager.getUsername(model.getElementAt(i).toString()).equals(infoUsername))
                {
                    list.setSelectedIndex(i);
                    return;
                }
            }
        }
    }
    
    public void updatePropsDialog(SubmissionInfo info)
    {
        TableModel model = propsTable.getModel();
        model.setValueAt(info.submissionId == null ? "(No Submissions Found)" : info.submissionId, 0, 1);
        model.setValueAt(info.username, 1, 1);
        model.setValueAt(info.firstname, 2, 1);
        model.setValueAt(info.filename, 3, 1);
        model.setValueAt(info.dateSubmitted, 4, 1);
        model.setValueAt(info.grader, 5, 1);
        model.setValueAt(info.dateGraded, 6, 1);
    }
    
    public void displayPropsDialog(SubmissionInfo sub)
    {
        if (sub == null)
        {
            Component selectedComp = tabbedPane.getSelectedComponent();
            GradingList targetList = null;

            if (ungradedPanel.equals(selectedComp))
                targetList = ungradedList;

            else if (gradedPanel.equals(selectedComp))
                targetList = gradedList;

            int index = targetList.getSelectedIndex();

            if (index != -1)
            {
                String username = targetList.getSelectedValue().toString();
                int spaceIndex = username.indexOf(" ");
                if (spaceIndex >= 0)
                    username = username.substring(0, spaceIndex);
                sub = submissionsManager.getSubmissionInfo(username);
            }
        }
        
        if (sub != null)
        {
            updatePropsDialog(sub);
            propsDialog.pack();
            propsDialog.setVisible(true);
            DisplayHelper.centralizePosition(propsDialog, this);            
        }
    }
    
    private void displayPropsDialog() 
    {
        displayPropsDialog(null);
    }       

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        gradingPanelPopup = new javax.swing.JPopupMenu();
        showNameItem = new javax.swing.JMenuItem();
        showAllNamesItem = new javax.swing.JMenuItem();
        hideNameItem = new javax.swing.JMenuItem();
        hideAllNamesItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        changeTaskItem = new javax.swing.JMenuItem();
        signOutItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        propsItem = new javax.swing.JMenuItem();
        propsDialog = new javax.swing.JDialog();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        propsTable = new javax.swing.JTable();
        tabbedPane = new javax.swing.JTabbedPane();
        ungradedPanel = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        ungradedList = new newcrunch.grader.GradingList();
        gradedPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        gradedList = new newcrunch.grader.GradingList();

        showNameItem.setMnemonic(java.awt.event.KeyEvent.VK_N);
        showNameItem.setText("Show Name");
        showNameItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showNameItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(showNameItem);

        showAllNamesItem.setMnemonic(java.awt.event.KeyEvent.VK_A);
        showAllNamesItem.setText("Show All Names");
        showAllNamesItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showAllNamesItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(showAllNamesItem);

        hideNameItem.setMnemonic(java.awt.event.KeyEvent.VK_H);
        hideNameItem.setText("Hide Name");
        hideNameItem.setEnabled(false);
        hideNameItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideNameItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(hideNameItem);

        hideAllNamesItem.setMnemonic(java.awt.event.KeyEvent.VK_I);
        hideAllNamesItem.setText("Hide All Names");
        hideAllNamesItem.setEnabled(false);
        hideAllNamesItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideAllNamesItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(hideAllNamesItem);
        gradingPanelPopup.add(jSeparator1);

        changeTaskItem.setMnemonic(java.awt.event.KeyEvent.VK_C);
        changeTaskItem.setText("Change Lab Task");
        changeTaskItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                changeTaskItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(changeTaskItem);

        signOutItem.setMnemonic(java.awt.event.KeyEvent.VK_S);
        signOutItem.setText("Sign Out");
        signOutItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                signOutItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(signOutItem);
        gradingPanelPopup.add(jSeparator2);

        propsItem.setMnemonic(java.awt.event.KeyEvent.VK_P);
        propsItem.setText("Properties");
        propsItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                propsItemActionPerformed(evt);
            }
        });
        gradingPanelPopup.add(propsItem);

        propsDialog.setTitle("Submission Information");

        jPanel1.setPreferredSize(new java.awt.Dimension(468, 136));

        jScrollPane2.setPreferredSize(new java.awt.Dimension(452, 159));

        propsTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"Submission Id", null},
                {"Username", null},
                {"Name", null},
                {"Filename", null},
                {"Date Submitted", null},
                {"Grader", null},
                {"Date Graded", null}
            },
            new String [] {
                "Property", "Value"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        propsTable.getTableHeader().setReorderingAllowed(false);
        jScrollPane2.setViewportView(propsTable);
        propsTable.getColumnModel().getColumn(0).setHeaderValue("Property"); // NOI18N
        propsTable.getColumnModel().getColumn(1).setHeaderValue("Value"); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout propsDialogLayout = new javax.swing.GroupLayout(propsDialog.getContentPane());
        propsDialog.getContentPane().setLayout(propsDialogLayout);
        propsDialogLayout.setHorizontalGroup(
            propsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        propsDialogLayout.setVerticalGroup(
            propsDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE)
        );

        ungradedList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                ungradedListMouseClicked(evt);
            }
        });
        jScrollPane3.setViewportView(ungradedList);

        javax.swing.GroupLayout ungradedPanelLayout = new javax.swing.GroupLayout(ungradedPanel);
        ungradedPanel.setLayout(ungradedPanelLayout);
        ungradedPanelLayout.setHorizontalGroup(
            ungradedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)
        );
        ungradedPanelLayout.setVerticalGroup(
            ungradedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 272, Short.MAX_VALUE)
        );

        tabbedPane.addTab("Ungraded", ungradedPanel);

        gradedList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                gradedListMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(gradedList);

        javax.swing.GroupLayout gradedPanelLayout = new javax.swing.GroupLayout(gradedPanel);
        gradedPanel.setLayout(gradedPanelLayout);
        gradedPanelLayout.setHorizontalGroup(
            gradedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)
        );
        gradedPanelLayout.setVerticalGroup(
            gradedPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 272, Short.MAX_VALUE)
        );

        tabbedPane.addTab("Graded", gradedPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(tabbedPane)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    
    private void showNameItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showNameItemActionPerformed
        int index;
        Component selectedComp = tabbedPane.getSelectedComponent();
        if (ungradedPanel.equals(selectedComp))
        {
            if ((index = ungradedList.getSelectedIndex()) >= 0)
            {
                ungradedList.getGradingListModel().showName(index);
                ungradedList.repaint();
            }
        }
        else if (gradedPanel.equals(selectedComp))
        {
            if ((index = gradedList.getSelectedIndex()) >= 0)
            {
                gradedList.getGradingListModel().showName(index);
                gradedList.repaint();
            }
        }
    }//GEN-LAST:event_showNameItemActionPerformed

    private void showAllNamesItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showAllNamesItemActionPerformed
        Component selectedComp = tabbedPane.getSelectedComponent();
        
        if (ungradedPanel.equals(selectedComp))
        {
            ungradedList.getGradingListModel().showAllNames();
            ungradedList.repaint();
        }
        
        else if (gradedPanel.equals(selectedComp))
        {
            gradedList.getGradingListModel().showAllNames();     
            gradedList.repaint();
        }
    }//GEN-LAST:event_showAllNamesItemActionPerformed

    private void hideNameItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideNameItemActionPerformed
        int index;
        Component selectedComp = tabbedPane.getSelectedComponent();
        if (ungradedPanel.equals(selectedComp))
        {
            if ((index = ungradedList.getSelectedIndex()) >= 0)
            {
                ungradedList.getGradingListModel().hideName(index);
                ungradedList.repaint();
            }
        }
        else if (gradedPanel.equals(selectedComp))
        {
            if ((index = gradedList.getSelectedIndex()) >= 0)
            {
                gradedList.getGradingListModel().hideName(index);
                gradedList.repaint();
            }
        }
    }//GEN-LAST:event_hideNameItemActionPerformed

    private void hideAllNamesItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideAllNamesItemActionPerformed
        Component selectedComp = tabbedPane.getSelectedComponent();
        
        if (ungradedPanel.equals(selectedComp))
        {
            ungradedList.getGradingListModel().hideAllNames();
            ungradedList.repaint();
        }
        
        else if (gradedPanel.equals(selectedComp))
        {
            gradedList.getGradingListModel().hideAllNames();
            gradedList.repaint();
        }
    }//GEN-LAST:event_hideAllNamesItemActionPerformed

    private void ungradedListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_ungradedListMouseClicked
        processGradingListMouseClick(evt);
    }//GEN-LAST:event_ungradedListMouseClicked

    private void gradedListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_gradedListMouseClicked
        processGradingListMouseClick(evt);
    }//GEN-LAST:event_gradedListMouseClicked

    private void changeTaskItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changeTaskItemActionPerformed
        Container container = this.getParent();
        CardLayout layout = (CardLayout)container.getLayout();
        layout.show(container, "selectionDisplay"); 
    }//GEN-LAST:event_changeTaskItemActionPerformed

    private void signOutItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_signOutItemActionPerformed
        if (!rightPanel.hasModifiedTab() || 
                DisplayHelper.showConfirmFrame(this, "Sign out", 
                        "There are modified submission(s). Proceed with signing out?") == JOptionPane.OK_OPTION)
            Misc.getBaseGUI(this).reset();
    }//GEN-LAST:event_signOutItemActionPerformed

    private void propsItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_propsItemActionPerformed
        displayPropsDialog();
    }//GEN-LAST:event_propsItemActionPerformed
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem changeTaskItem;
    private newcrunch.grader.GradingList gradedList;
    private javax.swing.JPanel gradedPanel;
    private javax.swing.JPopupMenu gradingPanelPopup;
    private javax.swing.JMenuItem hideAllNamesItem;
    private javax.swing.JMenuItem hideNameItem;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JDialog propsDialog;
    private javax.swing.JMenuItem propsItem;
    private javax.swing.JTable propsTable;
    private javax.swing.JMenuItem showAllNamesItem;
    private javax.swing.JMenuItem showNameItem;
    private javax.swing.JMenuItem signOutItem;
    private javax.swing.JTabbedPane tabbedPane;
    private newcrunch.grader.GradingList ungradedList;
    private javax.swing.JPanel ungradedPanel;
    // End of variables declaration//GEN-END:variables
}
